home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!cs.odu.edu!Amiga-Request
- From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
- Newsgroups: comp.sources.amiga
- Subject: v90i132: ls 3.1 - UNIX-like ls utility, Part02/03
- Message-ID: <12129@xanth.cs.odu.edu>
- Date: 10 Apr 90 21:25:55 GMT
- Sender: tadguy@cs.odu.edu
- Reply-To: kim@uts.amdahl.com (Kim E. DeVaughn)
- Lines: 1388
- Approved: tadguy@cs.odu.edu (Tad Guy)
- X-Mail-Submissions-To: Amiga@cs.odu.edu
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: kim@uts.amdahl.com (Kim E. DeVaughn)
- Posting-number: Volume 90, Issue 132
- Archive-name: unix/ls-3.1/part02
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 3)."
- # Contents: src/lssup.a
- # Wrapped by tadguy@xanth on Tue Apr 10 17:22:48 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/lssup.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/lssup.a'\"
- else
- echo shar: Extracting \"'src/lssup.a'\" \(33907 characters\)
- sed "s/^X//" >'src/lssup.a' <<'END_OF_FILE'
- X* --------------------------------------------------------------------- *
- X* LSSUP.A - Assembly support routines for ls.c
- X* Written by Justin V. McCormick 89-07-24
- X* --------------------------------------------------------------------- *
- X IFD CAPE
- X CSYMFMT
- X BASEREG B
- X SMALLOBJ
- X ADDSYM
- X OPTIMON
- X IDNT "lssup.a"
- X ENDC
- X
- X
- XSYS MACRO *
- X IFGT NARG-2
- X FAIL !!!
- X ENDC
- X IFEQ NARG-2
- X MOVE.L \2,a6
- X ENDC
- X JSR LVO\1(a6)
- X ENDM
- X
- XXLVO MACRO *
- X XREF LVO\1
- X ENDM
- X
- X; Equates
- Xfib_DirEntryType EQU $4
- Xfib_FileName EQU $8
- Xfib_Size EQU $7C
- Xfib_NumBlocks EQU $80
- Xfib_DateStamp EQU $84
- Xfib_SIZEOF EQU $104
- X
- Xds_Days EQU $0
- Xds_Minute EQU $4
- Xds_Tick EQU $8
- X
- XLH_HEAD EQU $0
- XLN_PRED EQU $4
- XLN_SUCC EQU $0
- X
- Xfe_Node equ 0
- Xfe_Fib equ 8
- Xpr_ConsoleTask EQU $A4
- X
- XMEMF_CLEAR EQU $10000
- Xsp_Msg EQU $0
- Xsp_Pkt EQU $14
- Xsp_SIZEOF EQU $44
- Xdp_Link EQU $0
- Xdp_Port EQU $4
- Xdp_Arg1 EQU $14
- Xdp_Type EQU $8
- XACTION_SCREEN_MODE EQU $3E2
- XLN_NAME EQU $A
- XLN_PRI EQU $9
- XLN_TYPE EQU $8
- XMP_FLAGS EQU $E
- XMP_MSGLIST EQU $14
- XMP_SIGBIT EQU $F
- XMP_SIGTASK EQU $10
- XMP_SIZE EQU $22
- XNT_MSGPORT EQU $4
- XPA_SIGNAL EQU $0
- X
- X* Library offsets
- X XLVO AddPort
- X XLVO AddTail
- X XLVO AllocMem
- X XLVO AllocSignal
- X XLVO CopyMem
- X XLVO Debug
- X XLVO Examine
- X XLVO FindTask
- X XLVO FreeMem
- X XLVO FreeSignal
- X XLVO GetMsg
- X XLVO Input
- X XLVO Insert
- X XLVO IoErr
- X XLVO IsInteractive
- X XLVO Output
- X XLVO ParentDir
- X XLVO PutMsg
- X XLVO RawDoFmt
- X XLVO Read
- X XLVO RemPort
- X XLVO WaitForChar
- X XLVO WaitPort
- X XLVO Write
- X XLVO UnLock
- X
- X* External constants
- X XREF @AllocFib
- X XREF @CleanUp
- X XREF @stpcpy
- X XREF @strcat
- X XREF @strlen
- X XREF baddatestr
- X XREF badtimestr
- X XREF ColonStr
- X XREF datepat
- X XREF dayspermonth
- X XREF DOSBase
- X XREF gwbrstr
- X XREF LSFlags
- X XREF NoFindFmtStr
- X XREF NoRAMMsg
- X XREF RamNameStr
- X XREF SlashStr
- X XREF sortkey
- X XREF timepat
- X
- X SECTION CODE
- X* --------------------------------------------------------------------- *
- X* VOID *myalloc (LONG)
- X* d0 d0
- X* --------------------------------------------------------------------- *
- X XDEF @myalloc
- X@myalloc:
- X movem.l d2/a6,-(sp)
- X addq.l #4,d0 ;Include sizeof(LONG)
- X move.l d0,d2 ;Copy to survive AllocMem
- X moveq #0,d1 ;MEMF_ANYTHING
- X SYS AllocMem,4 ;AllocMem(size + 4, 0L)
- X tst.l d0 ;Got it?
- X beq.s 1$
- X movea.l d0,a6 ;Copy pointer
- X move.l d2,(a6)+ ;Stash size in first 4 bytes
- X move.l a6,d0 ;return final pointer in d0
- X1$
- X movem.l (sp)+,d2/a6
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* VOID myfree (VOID *)
- X* a0
- X* --------------------------------------------------------------------- *
- X XDEF @myfree
- X@myfree:
- X move.l a6,-(sp)
- X
- X lea -4(a0),a1 ;Put in sys reg
- X move.l (a1),d0 ;d0 = size to free
- X SYS FreeMem,4
- X
- X movea.l (sp)+,a6
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* void asprintf(wstr, formatstring, args)
- X* char *wstr;
- X* char *formatstring;
- X* char **args;
- X*
- X* Synopsis: Given formatstring and args to format, formats output to wstr.
- X* Similar to sprintf(), except doesn't handle floats.
- X* --------------------------------------------------------------------- *
- X XDEF asprintf
- Xasprintf:
- X link a5,#0
- X movem.l d0-d2/a0-a3/a6,-(sp) ;Save everything we might clobber
- X
- X* Call format function to convert fmtstring and args to buffer on the stack
- X movea.l 12(a5),a0 ;Grab format string
- X lea 16(a5),a1 ;Grab EA of arguments
- X lea kput1,a2 ;Grab EA of output subroutine
- X movea.l 8(a5),a3 ;Grab EA of dest workspace
- X SYS RawDoFmt,4 ;Format it into workspace
- X
- X movem.l (sp)+,d0-d2/a0-a3/a6 ;Restore registers
- X unlk a5 ;And stack frame
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* RawDoFmt() output routine for xprintf, called for each formatted char.
- X* Takes byte in d0 and puts in buffer pointed to by a3, then increments a3.
- X* --------------------------------------------------------------------- *
- X XDEF kput1
- Xkput1:
- X move.b d0,(a3)+
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* void GetWinBounds(width, height)
- X* long *width, *height;
- X* a0 a1
- X* Find current console window, determine width and height
- X* in terms of current font, update width and height VPARMS passed.
- X* --------------------------------------------------------------------- *
- Xheight EQU -4
- Xwidth EQU -8
- Xconid EQU -12
- Xpacket EQU -16
- Xrpport EQU -20
- Xrpstr EQU -40
- X
- X XDEF @GetWinBounds
- X@GetWinBounds:
- X link a5,#-44
- X movem.l d2-d4/a2/a6,-(sp)
- X
- X move.l a0,width(a5) ;Save width/height pointers on stack
- X move.l a1,height(a5)
- X
- X SYS Input,DOSBase(a4) ;Grab Input filehandle
- X move.l d0,d1
- X SYS IsInteractive ;IsInteractive(Input())?
- X tst.l d0
- X beq.s gwbnowbrep ;Nope, can't get a bounds report
- X SYS Output
- X move.l d0,d1
- X SYS IsInteractive ;IsInteractive(Output())?
- X tst.l d0
- X beq.s gwbnowbrep ;Nope, don't clutter output stream
- X
- X suba.l a1,a1
- X SYS FindTask,4 ;d0 = FindTask(0L), our process
- X movea.l d0,a0 ;Transfer to address reg
- X move.l pr_ConsoleTask(a0),conid(a5) ;Save proc->pr_ConsoleTask
- X tst.l conid(a5) ;Is there really a console there?
- X bne.s gwbgotcon ;Yep
- X
- Xgwbnowbrep:
- X* Else we cannot get a window bounds report from this source
- X moveq #23,d1 ;return H=23
- X moveq #77,d2 ; W=77
- X bra gwbupdate
- X
- Xgwbgotcon:
- X moveq #0,d4 ;Clear our success status register
- X
- X moveq #0,d0
- X movea.l d0,a0
- X jsr CreatePort
- X move.l d0,rpport(a5) ;rpport = CreatePort(0L, 0L)
- X beq gwbdone ;Oops, no signals or ram available!
- X moveq #sp_SIZEOF,d0
- X jsr @myalloc
- X move.l d0,packet(a5) ;packet = AllocBlock(sizeof(*packet))
- X beq gwbfreeport ;Oops, no ram, free up port
- X
- X* Okay, we got our process id, reply port, and packet
- X* Now toggle the console into raw mode
- X movea.l rpport(a5),a2
- X movea.l d0,a1
- X movea.l conid(a5),a0
- X moveq #1,d0
- X jsr SetConsoleType ;SetConsoleType(1L, conid, packet, rpport)
- X
- X* Request a window bounds report
- X SYS Output,DOSBase(a4)
- X move.l d0,d1
- X moveq #4,d3
- X lea gwbrstr(a4),a0
- X move.l a0,d2
- X SYS Write,DOSBase(a4) ;Write(Output(), "\2330 q", 4L);
- X cmpi.l #$0004,d0 ;Did the console choke on it?
- X bne gwbsetcook ;hmmm, see if we can back out gracefully
- X
- X* Read the report string into stack buffer, if there is one
- X move.l #10000,d2
- X SYS Input
- X move.l d0,d1
- X SYS WaitForChar ;WaitForChar(Input(), 10000L) (.01 secs)
- X tst.l d0 ;Did we get the report?
- X beq gwbsetcook ;Nope, must not be a report coming
- X
- X SYS Input
- X move.l d0,d1
- X moveq #16,d3 ;Don't let it get longer than 16 characters
- X lea rpstr(a5),a0 ;Point to input string area
- X move.l a0,d2
- X SYS Read ;Read(Input(), rpstr, 16L)
- X move.l d0,d4 ;Save read length while we close shop
- X
- X* Turn the console back to cooked mode pronto to avoid cursor blink
- Xgwbsetcook:
- X movea.l rpport(a5),a2
- X movea.l packet(a5),a1
- X movea.l conid(a5),a0
- X moveq #0,d0
- X jsr SetConsoleType ;SetConsoleType(0L, conid, packet, rpport)
- X
- X* Release resources we borrowed
- Xgwbfreepack:
- X move.l packet(a5),d0 ;Did we allocate a packet?
- X beq.s gwbfreeport ;nay, check for port to free
- X movea.l d0,a0
- X jsr @myfree ;Else FreeBlock(packet)
- X
- Xgwbfreeport:
- X move.l rpport(a5),d0 ;if (rpport)...
- X beq gwbdone ;nope
- X jsr DeletePort ;Else DeletePort(rpport)
- X
- X* Finally, sanity check window bounds report string
- X* d4 = length of report string according to Read()
- X cmpi.l #9,d4 ;Less than 8 characters returned?
- X ble gwbdone ;hmmm, phonky bounds report from DOS?
- X lea rpstr(a5),a2 ;a2 = rpstr
- X cmpi.b #';',4(a2) ;Matches a typical report template?
- X bne gwbdone ;nope, got some weird junk back?
- X cmpi.b #'r',-1(a2,d4.w) ;Last byte is 'r' for report?
- X bne gwbdone ;Nope, message fubar!
- X
- X* Parse the height and width variables from the field now
- X* Our report format looks like this in hex:
- X* 9b 31 3b 31 3b y2 y1 3b x2 x1 20 72
- X* Or in ascii:
- X* <0x9b>1;1;20;77 r
- X* Which would indicate a width of 77 cols and a height of 20 rows for
- X* the current console device
- X*
- X* REGS: a2 points to beginning of 'r' terminated string
- X
- X addq.w #5,a2 ;Point to first char of Y size
- X moveq #0,d1 ;Clear out work reg
- X
- X* Convert ascii rows value to LONG, update host data
- X move.b (a2)+,d1 ;Grab a Y
- X subi.w #'0',d1 ;Less ascii offset
- X cmpi.b #';',(a2) ;Any more Y digits?
- X beq.s 1$ ;Nope
- X mulu #10,d1 ;Else shift by 10
- X add.b (a2)+,d1 ;Add least significant Y digit
- X subi.b #'0',d1 ;Less ascii offset
- X cmpi.b #';',(a2) ;Any more Y digits?
- X beq.s 1$ ;Nope
- X mulu #$000a,d1 ;Else shift by 10
- X add.b (a2)+,d1 ;Add least significant Y digit
- X subi.b #'0',d1 ;Less ascii offset
- X ;We'll assume screen height < 999 rows
- X1$
- X* Convert ascii columns value to LONG, update host data
- X addq.w #1,a2 ;Move past the ';' separator
- X moveq #0,d2 ;Zap work reg
- X move.b (a2)+,d2 ;Grab msd of X
- X cmpi.b #' ',d2 ;Premature end?
- X beq gwbdone ;Huh, must be garbage - don't update VPARMS
- X cmpi.b #';',d2 ;Also a possible error
- X beq gwbdone
- X cmpi.b #'r',d2 ;And what about this?
- X beq gwbdone
- X
- X subi.b #'0',d2 ;Okay, adjust ascii offset
- X cmpi.b #' ',(a2) ;Hit end of report?
- X beq.s 2$ ;Yep
- X mulu #$000a,d2 ;Else shift by 10
- X add.b (a2)+,d2 ;Add next digit
- X subi.b #'0',d2 ;Ascii adjust
- X cmpi.b #' ',(a2) ;Hit end of report?
- X beq.s 2$ ;Yep
- X mulu #$000a,d2 ;Else shift by 10
- X add.b (a2),d2 ;Add next digit
- X subi.b #'0',d2 ;Ascii adjust
- X
- X2$
- Xgwbupdate:
- X* Finally, update parameters by reference
- X movea.l height(a5),a0 ;Grab height VPARM
- X move.l d1,(a0) ;*height = d1
- X movea.l width(a5),a0 ;Grab width VPARM
- X move.l d2,(a0) ;*width = d2
- X
- Xgwbdone:
- X movem.l (sp)+,d2-d4/a2/a6
- X unlk a5
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* void __asm SetConsoleType(flag, id, packet, port)
- X* register __d0 long flag;
- X* register __a0 struct Process *id;
- X* register __a1 struct StandardPacket *packet;
- X* register __a2 struct MsgPort *port;
- X*
- X* Flag = 1L -- Raw mode
- X* = 0L -- Cooked mode
- X* --------------------------------------------------------------------- *
- X XDEF SetConsoleType
- XSetConsoleType:
- X movem.l a2/a3/a5/a6,-(sp)
- X
- X movea.l a0,a3 ;Copy process pointer
- X movea.l a1,a5 ;Copy packet pointer
- X lea sp_Pkt(a5),a0 ;a0 = &packet->sp_Pkt
- X move.l a0,sp_Msg+LN_NAME(a5) ;p->sp_Msg.mn_Node.ln_Name = &p->sp_Pkt
- X lea sp_Msg(a5),a0 ;a0 = &packet->sp_Msg
- X move.l a0,sp_Pkt+dp_Link(a5) ;p->sp_Pkt.dp_Link = &p->sp_Msg
- X move.l a2,sp_Pkt+dp_Port(a5) ;p->sp_Pkt.dp_Port = replyport
- X move.l #ACTION_SCREEN_MODE,sp_Pkt+dp_Type(a5) ;Set function
- X
- X tst.w d0 ;On or Off?
- X beq 1$
- X move.l #-1,sp_Pkt+dp_Arg1(a5) ;RAW ON
- X bra.s 2$
- X1$
- X clr.l sp_Pkt+dp_Arg1(a5) ;RAW OFF
- X2$
- X movea.l a3,a0
- X movea.l a5,a1
- X SYS PutMsg,4 ;PutMsg(proc, packet)
- X
- X movea.l a2,a0
- X SYS WaitPort ;WaitPort(port)
- X movea.l a2,a0
- X SYS GetMsg ;(void)GetMsg(port)
- X
- X movem.l (sp)+,a2/a3/a5/a6
- X rts
- X
- X* ------------------------------------------------------------------------- *
- X* struct MsgPort *CreatePort(name, pri) (a0/d0)
- X* ------------------------------------------------------------------------- *
- X XDEF CreatePort
- XCreatePort:
- X movem.l d5/d7/a2/a5/a6,-(sp)
- X
- X move.l a0,a5 ;Save Name
- X move.l d0,d5 ;Save Pri
- X
- X* Allocate a free signal, crap out if we can't
- X moveq #-1,d0
- X SYS AllocSignal,4
- X cmp.l #-1,d0 ;Did we get a signal?
- X bne.s cpgotsig ;Yep
- X moveq #0,d0 ;Otherwise return NULL
- X bra cpdone
- X
- Xcpgotsig:
- X move.l d0,d7 ;Save our signal
- X
- X* Allocate memory for MsgPort
- X moveq #MP_SIZE,d0 ;Size of MsgPort
- X jsr @myalloc ;Allocate it
- X tst.l d0 ;Did we get it?
- X bne.s cpgotport ;Yep
- X
- X move.l d7,d0 ;Otherwise crap out, free signal
- X SYS FreeSignal
- X moveq #0,d0 ;Return NULL
- X bra cpdone
- X
- Xcpgotport:
- X move.l d0,a2 ;This is our new port!
- X move.l a5,LN_NAME(a2) ;port->mp_Node.ln_Name = name
- X move.b d5,LN_PRI(a2) ;port->mp_Node.ln_Pri = priority
- X move.b #NT_MSGPORT,LN_TYPE(a2) ;port->mp_Node.ln_Type = NT_MSGPORT
- X move.b #PA_SIGNAL,MP_FLAGS(a2) ;port->mp_Flags = PA_SIGNAL
- X move.b d7,MP_SIGBIT(a2) ;port->mp_SIGBIT = sigBit
- X suba.l a1,a1
- X SYS FindTask
- X move.l d0,MP_SIGTASK(a2) ;port->mp_SIGTASK = FindTask(0L)
- X
- X cmpa.l #0,a5 ;Is this a new name?
- X beq.s cpnoname ;Nope, add it to the msg list
- X
- X movea.l a2,a1
- X SYS AddPort ;Otherwise add this port
- X move.l a2,d0 ;Return port pointer
- X bra.s cpdone
- X
- Xcpnoname:
- X* Initialized New List head
- X lea MP_MSGLIST(a2),a0 ;a0 = &port->mp_MsgList
- X move.l a0,(a0) ;list->lh_Head = list
- X addq.l #4,(a0) ;list->lh_Head += 4L
- X clr.l 4(a0) ;list->lh_Tail = 0L
- X move.l a0,8(a0) ;list->lh_TailPred = list
- X move.l a2,d0 ;Return port pointer
- X
- Xcpdone:
- X movem.l (sp)+,d5/d7/a2/a5/a6
- X rts
- X
- X* ------------------------------------------------------------------------- *
- X* DeletePort(port)(d0)
- X* ------------------------------------------------------------------------- *
- X XDEF DeletePort
- XDeletePort:
- X movem.l a5/a6,-(sp)
- X
- X move.l d0,a5
- X movea.l $4,a6
- X tst.l LN_NAME(a5) ;Is there a name?
- X beq.s dpnoname
- X
- X move.l d0,a1
- X SYS RemPort ;RemPort(port)
- X
- Xdpnoname:
- X move.b #$ff,LN_TYPE(a5) ;port->mp_Node.ln_Type = 0xff
- X move.l #-1,MP_MSGLIST(a5) ;port->mp_MsgList.lh_Head = -1L
- X
- X moveq #0,d0
- X move.b MP_SIGBIT(a5),d0 ;d0 = port->mp_SigBit
- X SYS FreeSignal ;FreeSignal(d0)
- X
- X movea.l a5,a0
- X jsr @myfree ;FreeBlock(port)
- X
- X movem.l (sp)+,a5/a6
- X rts
- X
- X* ------------------------------------------------------------------------
- X* FibFileDate(fib_date, datestr, timestr)
- X* a0 a1 8(a5)
- X* struct DateStamp *fib_date;
- X* char *datestr, *timestr;
- X* Calculate date based on DateStamp structure and return a pointer
- X* to the formatted date string.
- X* ------------------------------------------------------------------------
- X XDEF @FibFileDate
- X@FibFileDate:
- X link a5,#0
- X movem.l d3-d7/a2-a3/a6,-(sp)
- X
- X movea.l a1,a3 ;a3 = datestr, 8(a5) = timestr
- X movea.l a0,a1 ;Grab datestamp pointer
- X moveq #78,d7 ;Initial year = 1978
- X
- X move.l (a1),d5 ;days = fib_date->ds_Days
- X blt ffdbaddate ;Hey! you can't be negative! Invalid date...
- X
- X* Determine what year it is
- X divu #1461,d5
- X move.l d5,d0 ;Stash it
- X ext.l d5
- X lsl.l #2,d5
- X add.l d5,d7 ;year += (days / 1461) * 4
- X
- X* Count how many months into that year
- Xffdgetmo:
- X swap d0 ;days %= 1461
- X move.w d0,d5
- X
- X1$ tst.w d5 ;Out of days yet?
- X beq.s 3$ ;Yep, done here
- X
- X move.w #365,d6 ;Else month_days = 365
- X move.w d7,d0 ;Grab year
- X andi.w #3,d0 ;if (year & 3) == 0 Leap year?
- X bne.s 2$ ;Nope
- X addq.w #1,d6 ;Otherwise bump month_days
- X
- X2$ cmp.w d6,d5 ;is day < month_days?
- X blt.s 3$ ;yep, done here
- X sub.w d6,d5 ;otherwise day -= month_days
- X
- X addq.l #1,d7 ; year++
- X bra 1$
- X3$
- X
- X* Count how many days into that month of that year
- Xffdgetday:
- X;for (i = 0, day++; i < 12; i++)
- X moveq #0,d4 ;current month = 0
- X moveq #0,d6 ;Zap hinybs
- X addq.w #1,d5
- X lea dayspermonth(a4),a0
- X
- X1$
- X move.b 0(a0,d4.w),d6 ;month_days = dayspermonth[i]
- X
- X cmpi.w #1,d4 ;if (i == 1 && (year & 3) == 0)
- X bne.s 2$
- X move.w d7,d0
- X andi.w #3,d0
- X bne.s 2$
- X addq.w #1,d6 ;month_days++
- X
- X2$ cmp.w d6,d5 ;if (day <= month_days)
- X ble.s 4$ ;Break out, found the right month
- X
- X sub.w d6,d5 ;Else, day -= month_days
- X
- X addq.w #1,d4 ;i++
- X3$ cmpi.w #12,d4 ;Done all months yet?
- X blt 1$ ;Nope
- X
- X4$
- Xffdprint:
- X1$ cmpi.l #99,d7 ;while (year >= 100)
- X ble.s 2$
- X subi.l #100,d7 ;year -= 100
- X bra 1$
- X2$
- X;asprintf(datestr, "%02d-%02d-%02d %02d:%02d:%02d", i + 1, day, year, hour, min, sec)
- X move.l 8(a1),d0 ;sec = fib_date->ds_Tick / 50;
- X divu #50,d0
- X ext.l d0
- X move.l d0,-(sp) ;Push secs
- X move.l 4(a1),d0 ;min = fib_date->ds_Minute
- X move.l d0,d1 ;Clone it
- X divu #60,d0
- X moveq #0,d3
- X move.w d0,d3 ;hour = min / 60
- X mulu #60,d0
- X sub.w d0,d1 ;min -= hour * 60
- X move.l d1,-(sp) ;Push mins
- X move.l d3,-(sp) ;Push hours
- X pea timepat(a4) ;Push the format pattern
- X move.l 8(a5),-(sp) ;Push destination buffer, datestr
- X jsr asprintf
- X lea 20(sp),sp
- X
- X move.l d5,-(sp) ;Push day
- X addq.w #1,d4 ;Push month (offset by 1!)
- X move.l d4,-(sp)
- X move.l d7,-(sp) ;Push year
- X pea datepat(a4) ;Push the format pattern
- X move.l a3,-(sp) ;Push destination buffer
- X jsr asprintf
- X lea 20(sp),sp
- X
- Xffddone:
- X movem.l (sp)+,d3-d7/a2-a3/a6
- X unlk a5
- X rts
- X
- Xffdbaddate:
- X lea badtimestr(a4),a1 ;stpcpy (timestr, "00:00:00");
- X movea.l 8(a5),a0
- X jsr @stpcpy
- X lea baddatestr(a4),a1 ;stpcpy (datestr, "00-00-00");
- X movea.l a3,a0
- X jsr @stpcpy
- X bra ffddone
- X
- X*----------------------------------------------------------------------
- X* LONG iswild(name)
- X* char *name;
- X* a0
- X* Search a string for wild characters, return 1 if found
- X*----------------------------------------------------------------------
- X XDEF @iswild
- X@iswild:
- X moveq #0,d0 ;Clear out our character register
- Xischk1:
- X move.b (a0)+,d0 ;Grab a char
- X beq.s iwdone ;Might be end of string?
- X cmpi.b #'*',d0 ;Is it *?
- X beq.s iswdone ;yep, is wild
- X cmpi.b #'?',d0 ;Is it a qmark
- X bne.s ischk1 ;Nope, check next character
- X
- Xiswdone:
- X moveq #1,d0
- Xiwdone:
- X rts
- X
- X* ------------------------------------------------------------------------
- X; Compare a wild card name with a normal name
- X; LONG wildmatch (name, wild)
- X; char *name, *wild;
- X; a0 a1
- X* ------------------------------------------------------------------------
- X XDEF @wildmatch
- X@wildmatch:
- X link a5,#-64
- X movem.l d3/a2-a3,-(sp)
- X
- X movea.l a0,a2 ;Grab name
- X movea.l a1,a3 ;Grab pattern
- X lea -64(a5),a0 ;back[0][0]
- X lea -60(a5),a1 ;back[0][1]
- X
- X moveq #0,d3 ;bi = 0
- X
- Xwmloop1:
- X tst.b (a2) ;End of name?
- X bne.s wmnoteon
- X tst.b (a3) ;End of pattern?
- X beq wmmatched ;Yep, we matched
- X
- Xwmnoteon:
- X cmpi.b #'*',(a3) ;Is it a splat?
- X bne.s wmnotstar ;Nope, maybe '?'
- X
- X cmpi.w #64,d3 ;Have we hit max expression depth?
- X beq wmnomatch ;Yep, ran out of room in recursion table
- X
- X;back[bi][0] = w
- X move.l a3,0(a0,d3.w) ;Stash pointer to this '*' in table
- X
- X;back[bi][1] = n
- X move.l a2,0(a1,d3.w)
- X
- X addq.w #8,d3 ;++bi
- X addq.w #1,a3 ;++w
- X bra.s wmloop1 ;Check next
- X
- Xwmgoback:
- X subq.w #8,d3 ;--bi
- X move.l a0,d0
- Xwmback1:
- X tst.w d3 ;while (bi >= 0 && *back[bi][1] == '\x0')
- X blt.s wmbacked
- X movea.l 0(a1,d3.l),a0
- X tst.b (a0)
- X bne.s wmbacked
- X
- X subq.w #8,d3 ;--bi
- X bra.s wmback1
- X
- Xwmbacked:
- X tst.w d3 ;if (bi < 0)
- X blt.s wmnomatch ;return (0)
- X
- X movea.l d0,a0
- X movea.l 0(a0,d3.w),a3 ;w = back[bi][0] + 1
- X addq.w #1,a3
- X
- X addq.l #1,0(a1,d3.w)
- X movea.l 0(a1,d3.l),a2 ;n = ++back[bi][1]
- X
- X addq.w #8,d3 ;++bi
- X bra.s wmloop1
- X
- Xwmnotstar:
- X cmpi.b #'?',(a3) ;Is it '?'
- X bne.s wmnotqmark
- X
- X tst.b (a2) ;Reached end of string?
- X bne.s wmincpoint ;Nope, move on to next char
- X
- X tst.w d3 ;Are we at top level of expression?
- X beq.s wmnomatch ;Yep, expression didn't match
- X bra.s wmgoback ;Otherwise pop a level and try to match
- X
- Xwmnotqmark:
- X move.b (a2),d0 ;Grab a char from bstr
- X cmpi.b #$40,d0 ;less than @ character?
- X bls.s 1$ ;Yep
- X cmpi.b #$5a,d0 ;Greater than Z?
- X bhi.s 1$ ;Yep
- X addi.b #$20,d0
- X1$
- X move.b (a3),d1 ;Grab a char from bstr
- X cmpi.b #$40,d1 ;less than @ character?
- X bls.s 2$ ;Yep
- X cmpi.b #$5a,d1 ;Greater than Z?
- X bhi.s 2$ ;Yep
- X addi.b #$20,d1
- X2$
- X cmp.b d0,d1 ;*n = *w?
- X beq.s wmincpoint ;Yep, move on past
- X
- X tst.w d3 ;Are we at top expression level?
- X beq.s wmnomatch ;Yep, they didn't match
- X bra.s wmgoback ;Nope, process next part
- X
- Xwmincpoint:
- X tst.b (a2) ;Done with name?
- X beq.s wmnamend ;Yep
- X addq.w #1,a2 ;Otherwise increment name pointer
- X
- Xwmnamend:
- X tst.b (a3) ;End of pattern?
- X beq.s wmmatched ;Yep, we matched
- X addq.w #1,a3 ;Otherwise inc wild pointer, match next char
- X bra wmloop1
- X
- Xwmmatched:
- X moveq #1,d0
- X bra.s wmdone
- X
- Xwmnomatch:
- X moveq #0,d0
- X
- Xwmdone:
- X movem.l (sp)+,d3/a2-a3
- X unlk a5
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* BOOL CompFibs (keytype, a, b)
- X* d0 a0 a1
- X* LONG keytype;
- X* struct FileInfoBlock *a, *b;
- X*
- X* Used by SortFibs to determine precedence of Fibs.
- X* keytype is one of 0, 1, or 2:
- X* 0=alpha, 1=size, 2=date
- X* --------------------------------------------------------------------- *
- X XDEF @CompFibs
- X@CompFibs:
- X movem.l d2-d3/a2,-(sp)
- X
- X move.l d0,d2 ;Stash keytype
- X
- X* Prioritize Dirs/Files?
- X move.l LSFlags(a4),d3 ;Grab flags
- X
- X btst.l #17,d3 ;LSFlags & MIXFILEDIRS?
- X bne.s cftstsort ;Yep, don't bother comparing EntryTypes
- X
- X move.l fib_DirEntryType(a0),d0
- X cmp.l fib_DirEntryType(a1),d0
- X blt.s 1$ ;a0 is < a1, (dir < file)
- X beq.s cftstsort ;a0 is == a1, try next test
- X
- X moveq #0,d0 ;a0 is > a1, (file > dir)
- X bra.s 2$
- X1$
- X moveq #1,d0 ;greater than, (dir < file)
- X
- X2$ btst.l #16,d3 ;LSFlags & FILESFIRST?
- X beq cfexit0 ;Nope, default Dirs first
- X bchg.l #0,d0 ;Else d0 ^= 1, reverse sense
- X bra cfexit0
- X
- X* Both entries are the same type, now see about sorting them
- Xcftstsort:
- X btst.l #6,d3 ;LSFlags & NOSORTFLAG set?
- X bne cffalse ;Yep, always AddTail to list
- X
- X* Switch keytype
- X tst.w d2 ;Alphabetize?
- X bne.s cfnalpha ;Nope
- X
- X* Compare lexigraphically, ignoring case differences
- Xcfalpha:
- X lea fib_FileName(a0),a0 ;a = &Fipb->fib_FileName
- X lea fib_FileName(a1),a1 ;b = &Fipb->fib_FileName
- X
- X; for(; *a && tolower(*a) == tolower(*b); a++, b++);
- Xlccstart:
- X tst.b (a0) ;Is there a char here at source?
- X beq.s lcceostr ;Nope, fell off the end
- X
- X move.b (a1)+,d1 ;Grab a char from bstr
- X cmpi.b #$40,d1 ;less than @ character?
- X bls.s 1$ ;Yep
- X cmpi.b #$5a,d1 ;Greater than Z?
- X bhi.s 1$ ;Yep
- X addi.b #$20,d1
- X1$
- X move.b (a0)+,d0 ;Grab a char from astr
- X cmpi.b #$40,d0 ;less than @ character?
- X bls.s 2$ ;Yep
- X cmpi.b #$5a,d0 ;Greater than Z?
- X bhi.s 2$ ;Yep
- X addi.b #$20,d0
- X2$
- X cmp.b d0,d1 ;are they the same?
- X beq lccstart ;Yep, compare next pair of chars
- X
- Xlcceostr:
- X sub.b d1,d0 ;return(tolower(*astr) - tolower(*bstr))
- X bgt.s cftrue ; > 0?, return TRUE
- X bra.s cffalse ;Else return FALSE
- X
- Xcfnalpha:
- X subq.w #1,d2 ;Size?
- X bne.s cfnsize ;Nope
- X
- X* Compare fib_Sizes
- X move.l fib_Size(a0),d0 ;d0 = afib->fib_Size
- X cmp.l fib_Size(a1),d0 ;b->fib_Size > a->fib_Size?
- X bgt.s cftrue ;Yep, return TRUE
- X blt.s cffalse ;<, return FALSE
- X bra cfalpha ;Else it's a tie, alphabetize
- X
- Xcfnsize:
- X* Compare fib_DateStamps
- X lea fib_DateStamp(a0),a0 ;a = &afib->fib_DateStamp
- X lea fib_DateStamp(a1),a1 ;b = &bfib->fib_DateStamp
- X jsr @CompareDateStamps
- X tst.l d0
- X beq cfalpha ;its the same date?, alphabetize
- X blt.s cffalse
- Xcftrue:
- X moveq #1,d0
- X bra.s cfexit
- Xcffalse:
- X moveq #0,d0
- Xcfexit:
- X btst.l #9,d3 ;LSFlags & REVFLAG?
- X beq.s 1$ ;Nope
- X bchg.l #0,d0 ;Else invert boolean result
- X1$
- Xcfexit0:
- X movem.l (sp)+,d2-d3/a2
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* LONG CompareDateStamps(adate, bdate)
- X* d0 a0 a1
- X* struct DateStamp *adate, *bdate;
- X* --------------------------------------------------------------------- *
- X XDEF @CompareDateStamps
- X@CompareDateStamps:
- X move.l ds_Days(a0),d0 ;d0 = adate->ds_Days
- X sub.l ds_Days(a1),d0 ;b->ds_Days > a->ds_Days?
- X bne.s 1$ ;Return b->day - a->day
- X
- X;They are the same day, check min/tick
- X move.l ds_Minute(a0),d0
- X sub.l ds_Minute(a1),d0 ;d0 = amin - bmin
- X muls #3000,d0 ; * 3000
- X add.l ds_Tick(a0),d0
- X sub.l ds_Tick(a1),d0 ; + atick - btick
- X1$
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* VOID InsertFibNode(hfib, newfib)
- X* a0 a1
- X* struct List *hfib;
- X* struct FibEntry *newfib;
- X*
- X* Compare data in newfib->Fib with nodes in the list until we
- X* find the insertion point.
- X* --------------------------------------------------------------------- *
- X XDEF @InsertFibNode
- X@InsertFibNode:
- X movem.l d2/a2-a3/a5/a6,-(sp)
- X
- X move.l sortkey(a4),d2
- X movea.l a0,a3 ;a3 = hfib
- X movea.l a1,a2 ;a2 = newfib
- X
- X movea.l LH_HEAD(a3),a5 ;afib = hfib->lh_Head
- X
- X1$ tst.l fe_Node+LN_SUCC(a5) ;afib->fe_Node.mln_Succ != 0?
- X beq.s 4$
- X
- X movea.l fe_Fib(a2),a1
- X movea.l fe_Fib(a5),a0
- X move.l d2,d0
- X jsr @CompFibs ;CompFibs(sortkey, afib->Fib, newfib->Fib)
- X tst.w d0
- X bne.s 4$
- X movea.l fe_Node+LN_SUCC(a5),a5 ;afib = afib->fe_Node.mln_Succ
- X bra 1$
- X
- X4$ movea.l a3,a0 ;a0 = List *
- X movea.l a2,a1 ;a1 = Node *
- X movea.l fe_Node+LN_PRED(a5),a2 ;a2 = Pred *
- X SYS Insert,4 ;Insert(hfib, newfib, afib->fe_Node.mln_Succ)
- X
- X movem.l (sp)+,d2/a2-a3/a5/a6
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* LONG FillFibEntry (headfib, fibp)
- X* a0 a1
- X* struct List *headfib;
- X* struct FileInfoBlock *fibp;
- X* --------------------------------------------------------------------- *
- X XDEF @FillFibEntry
- X@FillFibEntry:
- X movem.l a2-a3/a5/a6,-(sp)
- X movea.l a0,a2 ;a2 = head of list
- X movea.l a1,a3 ;a3 = fileinfoblock
- X
- X jsr @AllocFib ;Allocate a new fib
- X tst.l d0 ;Got it?
- X beq.s 3$ ;Nope, return 0
- X movea.l d0,a5 ;a5 = tfibp = AllocFib()
- X
- X move.l #fib_SIZEOF,d0
- X movea.l fe_Fib(a5),a1
- X movea.l a3,a0
- X SYS CopyMem,4 ;CopyMem(fibp, tfibp->Fib, sizeof(struct fib))
- X
- X movea.l a5,a1
- X movea.l a2,a0
- X
- X jsr @InsertFibNode ;InsertFibNode(headfib, tfibp)
- X
- X moveq #1,d0 ;return(1)
- X3$
- X movem.l (sp)+,a2-a3/a5/a6
- X rts
- X
- X* --------------------------------------------------------------------- *
- X XDEF @nullstub
- X@nullstub:
- X moveq #0,d0
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* LONG GetPathString (dest, src)
- X* d0 a0 a1
- X* BYTE *dest, *src;
- X* --------------------------------------------------------------------- *
- X XDEF @GetPathString
- X@GetPathString:
- X move.l a2,-(sp)
- X
- X moveq #0,d0 ;Zero return dest length
- X
- X* Find end of src string
- X movea.l a1,a2 ;Save src start address
- X1$ tst.b (a1)+ ;while (*src++ != 0)
- X bne 1$
- X
- X* Work backwards till we find a ':' or a '/'
- X2$ move.b -(a1),d1 ;c = *(--src)
- X cmpi.b #':',d1 ;Hit a colon?
- X beq.s 4$ ;Yep, found our path end
- X cmpi.b #'/',d1 ;Hit a slash?
- X bne.s 3$ ;Nope, try next char
- X cmpa.l a2,a1 ;At first char?
- X beq.s 4$ ;Yep, leave the single slash
- X cmpi.b #'/',-1(a1) ;Next char back is also a '/'?
- X beq.s 4$ ;Yep, allow multiple slashes
- X subq.w #1,a1 ;Else backup to previous char, eliminate '/'
- X bra.s 4$
- X3$
- X cmpa.l a2,a1 ;Back at start of src?
- X bhi 2$ ;Nope, try previous src char
- X bra.s gpsdone ;Else no dest, return
- X4$
- X* Copy path portion to dest
- Xgpscpy:
- X cmpa.l a2,a1 ;Past end address?
- X bcs.s gpsdone ;Yep, terminate
- X move.b (a2)+,(a0)+ ;Copy a char from src to dest
- X addq.w #1,d0 ;Bump dest length count
- X bra gpscpy ;Check end address
- Xgpsdone:
- X clr.b (a0) ;Null terminate dest
- X
- X movea.l (sp)+,a2
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* LONG GetFileString (dest, src)
- X* d0 a0 a1
- X* BYTE *dest, *src;
- X* --------------------------------------------------------------------- *
- X XDEF @GetFileString
- X@GetFileString:
- X move.l a2,-(sp)
- X
- X moveq #0,d0 ;Zero return dest length
- X
- X* Find end of src string
- X movea.l a1,a2 ;Save src start address
- X1$ tst.b (a1)+ ;while (*src++ != 0)
- X bne 1$
- X
- X* Work backwards till we find a ':' or a '/'
- X2$ move.b -(a1),d1 ;c = *(--src)
- X cmpi.b #':',d1 ;Hit a colon?
- X beq.s 4$ ;Yep, found our path end
- X cmpi.b #'/',d1 ;Hit a slash?
- X beq.s 4$ ;Nope, try next char
- X3$
- X cmpa.l a2,a1 ;Back at start of src?
- X bhi 2$ ;Nope, try previous src char
- X bra.s gfscpy ;Else no path, entire src is filename
- X4$
- X addq.w #1,a1 ;Move past ':' or '/'
- X
- X* Copy name portion to dest
- Xgfscpy:
- X move.b (a1)+,(a0)+ ;Copy a char from src to dest
- X beq.s 2$
- X addq.w #1,d0 ;Bump dest length count
- X bra gfscpy ;Check end address
- X2$
- X movea.l (sp)+,a2
- X rts
- X
- X* ------------------------------------------------------------------------- *
- X* BYTE *astrncpy(dst, src, len)
- X* d0/a0 a0 a1 d0
- X* Takes text in a1, copies d0 bytes to text in a0.
- X* a0 returns pointing to null at end of final text.
- X* Dest text is always null terminated.
- X* ------------------------------------------------------------------------- *
- X XDEF @astrncpy
- X@astrncpy:
- X1$ subq.l #1,d0 ;Dec count
- X blt.s 2$ ;Done!
- X
- X move.b (a1)+,(a0)+ ;Copy a byte
- X bne 1$ ;Do until end of src or cnt < 0
- X2$
- X clr.b (a0) ;Null terminate dest
- X move.l a0,d0 ;Return in d0 also
- X rts
- X
- X* ------------------------------------------------------------------------- *
- X* VOID amovmem(src, dst, len)
- X* a0 a1 d0
- X* Takes text in a0, copies d0 bytes to text in a1. Correctly handles
- X* overlapping memory.
- X* ------------------------------------------------------------------------- *
- X XDEF amovmem
- Xamovmem:
- X cmpa.l a0,a1 ;Low to high or high to low?
- X bcs.s 2$ ;High to low, copy forward
- X adda.w d0,a0 ;Else start at end, copy backward
- X adda.w d0,a1
- X
- X1$ move.b -(a0),-(a1)
- X subq.w #1,d0
- X bgt 1$
- X bra.s amdone
- X
- X2$ move.b (a0)+,(a1)+
- X subq.w #1,d0
- X bgt 2$
- Xamdone:
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* BYTE *aindex(BYTE *, BYTE);
- X* d0 a0 d0
- X* --------------------------------------------------------------------- *
- X XDEF @aindex
- X@aindex:
- X1$ cmp.b (a0),d0
- X beq.s aifound
- X tst.b (a0)+
- X beq.s ainomatch
- X bra 1$
- X
- Xainomatch:
- X moveq #0,d0
- X rts
- X
- Xaifound:
- X move.l a0,d0
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* LONG MakePathString(lock, dest)
- X* a0 a1
- X* struct FileLock *lock;
- X* BYTE *dest;
- X*
- X* DESCRIPTION:
- X* Given text and a filelock, construct entire pathname and
- X* return in dest.
- X* --------------------------------------------------------------------- *
- X XDEF @MakePathString
- X@MakePathString:
- X movem.l d2-d5/d7/a2-a3/a6,-(sp)
- X
- X* Grab pointer to lock and dest text to fill
- X move.l a0,d3 ;d3 = lock
- X movea.l a1,a2 ;a2 = dest
- X clr.b (a2) ;NULL terminate dest
- X moveq #0,d5 ;LockFlag = 0
- X
- X* Allocate a FileInfoBlock for local use
- X move.l #fib_SIZEOF,d0
- X jsr @myalloc
- X move.l d0,d7 ;d7 = *fib
- X beq mpsfailed ;Whoops no mem? return!
- X
- X movea.l DOSBase(a4),a6 ;DOSBase calls from here on
- X
- X* while (lock != 0)
- X1$
- X tst.l d3 ;Got a lock?
- X beq.s mpsokay ;Nope, must be at root
- X
- X* Examine the current lock
- X move.l d3,d1
- X move.l d7,d2
- X SYS Examine ;Examine(lock, fib)
- X tst.l d0 ;Okay?
- X beq.s mpsfailed ;Nope, some sort of dos failure?
- X
- X movea.l d7,a1
- X cmpi.b #' ',fib_FileName(a1) ;if (fib->fib_FileName[0] >= ' ')
- X bcs.s 3$ ;Nope, don't bother inserting?
- X
- X tst.b (a2) ;if (dest[0] != 0)
- X beq.s 2$
- X lea SlashStr(a4),a1
- X movea.l a2,a0
- X jsr @InsertPathString ;InsertPathString(dest, "/");
- X2$
- X movea.l d7,a1
- X lea fib_FileName(a1),a1
- X movea.l a2,a0
- X jsr @InsertPathString ;InsertPathString(dest, fib->fib_FileName)
- X3$
- X* Okay, move up one directory
- X move.l d3,d4 ;oldlock = lock
- X
- X move.l d3,d1
- X SYS ParentDir
- X move.l d0,d3 ;lock = ParentDir(lock)
- X
- X tst.w d5 ;LockFlag set?
- X bne.s 4$ ;Yep, unlock
- X moveq #1,d5 ;Else LockFlag = 1, unlock next time
- X bra 1$ ;Next directory up
- X4$
- X move.l d4,d1
- X SYS UnLock ;UnLock(oldlock)
- X bra 1$ ;Examine
- X
- Xmpsokay:
- X* See if root was RAM:, special case
- X movea.l d7,a1 ;a1 = fib
- X cmpi.b #' ',fib_FileName(a1) ;if (fib->fib_FileName[0] >= ' ')
- X bcc.s 1$ ;Yep, not 1.1/1.2 RAM:
- X lea RamNameStr(a4),a1 ;Else...
- X movea.l a2,a0
- X jsr @InsertPathString ;InsertPathString(dest, "RAM:")
- X bra.s mpsdone
- X1$
- X* Find last slash we tacked on, change to a colon, or, add a colon
- X moveq #'/',d0
- X movea.l a2,a0
- X jsr @aindex ;d0 = strchr(dest, '/')
- X tst.l d0 ;Do we have a slash?
- X beq.s 2$ ;Nope, at root....
- X movea.l d0,a0
- X move.b #':',(a0) ;Else change first '/' to a ':'
- X bra.s mpsdone
- X
- X* No slash, must be locked at the root. Append a colon to the dest.
- X2$
- X lea ColonStr(a4),a1
- X movea.l a2,a0
- X jsr @strcat ;strcat (dest, ":")
- X bra.s mpsdone
- X
- X* Come here if an error occured, return empty text to caller
- Xmpsfailed:
- X clr.b (a2) ;dest[0] = (BYTE)0
- X moveq #0,d3 ;return (0L)
- X bra.s mpsdeall
- X
- X* Come here if everything is okay, deallocate FileInfoBlock
- Xmpsdone:
- X moveq #1,d3 ;return (1L)
- X
- Xmpsdeall:
- X tst.l d7 ;Did we allocate a fib?
- X beq.s mpsfinis ;nope
- X movea.l d7,a0 ;Else free the memory
- X jsr @myfree
- X
- Xmpsfinis:
- X move.l d3,d0 ;Put return value in d0
- X movem.l (sp)+,d2-d5/d7/a2-a3/a6
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* VOID InsertPathString(dest, source)
- X* a0 a1
- X* BYTE *dest, *source;
- X*
- X* DESCRIPTION:
- X* Insert source text into dest text.
- X* Special case for source length == 0, source must be RAM.
- X* --------------------------------------------------------------------- *
- X XDEF @InsertPathString
- X@InsertPathString:
- X movem.l d7/a2-a3,-(sp)
- X
- X movea.l a1,a3 ;a3 = source
- X move.l a0,a2 ;a2 = dest
- X
- X movea.l a3,a0
- X jsr @strlen
- X move.l d0,d7 ;d7 = strlen(source)
- X
- X1$ movea.l a2,a0
- X jsr @strlen ;d0 = strlen(dest)
- X
- X addq.w #1,d0 ;Bump the length to include zero byte at end
- X movea.l a2,a1
- X adda.w d7,a1 ;Push dest + slen
- X movea.l a2,a0 ;Push dest
- X jsr amovmem ;amovmem(dest, dest + slen, strlen(dest) + 1)
- X
- X move.w d7,d0
- X movea.l a2,a1
- X movea.l a3,a0
- X jsr amovmem ;amovmem(source, dest, slen)
- X
- X movem.l (sp)+,d7/a2-a3
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* VOID NoMemExit(VOID)
- X* --------------------------------------------------------------------- *
- X XDEF @NoMemExit
- X@NoMemExit:
- X moveq #103,d1
- X moveq #20,d0
- X lea NoRAMMsg(a4),a0
- X jsr @CleanUp
- X rts
- X
- X* --------------------------------------------------------------------- *
- X* VOID NoFileExit(name)
- X* a0
- X* BYTE *name;
- X* --------------------------------------------------------------------- *
- X XDEF @NoFileExit
- X@NoFileExit:
- X movem.l d2-d4/a6,-(sp)
- X
- X move.l a0,d2 ;Save name
- X SYS IoErr,DOSBase(a4) ;Get IoError status
- X move.l d0,d3 ;Save it
- X
- X move.l #300,d0
- X jsr @myalloc
- X move.l d0,d4 ;d3 = myalloc( 300 )
- X bne.s 1$ ;Got it!
- X jsr @NoMemExit ;else exit with No Ram message
- X bra.s 2$
- X1$
- X move.l d2,-(sp)
- X pea NoFindFmtStr(a4)
- X move.l d4,-(sp)
- X jsr asprintf ;asprintf(tstr, NoFindFmtStr, name)
- X lea 12(sp),sp
- X
- X move.l d3,d1
- X moveq #20,d0
- X movea.l d4,a0
- X jsr @CleanUp ;CleanUp(tstr, 20L, IoErr())
- X ; a0 d0 d1
- X move.l d4,a0
- X jsr @myfree ;free (tstr)
- X2$
- X movem.l (sp)+,d2-d4/a6
- X rts
- X
- X* --------------------------------------------------------------------- *
- X END
- X* --------------------------------------------------------------------- *
- END_OF_FILE
- if test 33907 -ne `wc -c <'src/lssup.a'`; then
- echo shar: \"'src/lssup.a'\" unpacked with wrong size!
- fi
- # end of 'src/lssup.a'
- fi
- echo shar: End of archive 2 \(of 3\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
- Mail comments to the moderator at <amiga-request@cs.odu.edu>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-